package com.kyh.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public final class DateUtil {

	public static final String PATTERN_1 = "yyyyMMddHHmmss";
	public static final String PATTERN_2 = "yyyy-MM-dd HH:mm:ss";
	public static final String PATTERN_3 = "yyyyMMddHHmmssSSS";
	public static final String PATTERN_4 = "yyyy-MM-dd";
	
	public static SimpleDateFormat sdfYYYY_MM = new SimpleDateFormat("yyyy-MM");
	
	public static SimpleDateFormat sdfYYYY_MM_DD = new SimpleDateFormat(PATTERN_4);
	
	public static SimpleDateFormat sdfYYYY_MM_DD_HH_mm_ss = new SimpleDateFormat(PATTERN_2);

	/**
	 * 添加一天
	 */
	public static Date addOneDay(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_MONTH, 1);
		
		return c.getTime();
	}

	/**
	 * 添加N天
	 */
	public static Date addDays(Date date, int n) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_MONTH, n);
		
		return c.getTime();
	}

	/**
	 * 添加一月
	 */
	public static Date addOneMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, 1);
		
		return c.getTime();
	}

	/**
	 * 添加N月
	 */
	public static Date addMonth(Date date, int n) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, n);
		
		return c.getTime();
	}

	public static Date parseYYYY_MM_dd(String dateStr) {
		if (dateStr == null || (dateStr.length() != 8 && dateStr.length() != 9 && dateStr.length() != 10)) {
			return null;
		}
		try {
			return sdfYYYY_MM_DD.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static Date parseYMdHms(String dateStr) {
		if (dateStr == null || (dateStr.length() != 17 && dateStr.length() != 18 && dateStr.length() != 19)) {
			return null;
		}
		try {
			return sdfYYYY_MM_DD_HH_mm_ss.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static Date parse(String dateStr, String pattern) {
		try {
			return new SimpleDateFormat(pattern).parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * date转字符串
	 */
	public static String dateToStr(Date date, String pattern) {
		if (date == null) {
			return null;
		}
		return new SimpleDateFormat(pattern).format(date);
	}

	/**
	 * 获取YYYY格式
	 */
	public static String getYear() {
		SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");
		return sdfYear.format(new Date());
	}

	/**
	 * 获取当前月份
	 */
	public static String getMonth() {
		Calendar cal = Calendar.getInstance();
		int month = cal.get(Calendar.MONTH) + 1;
		if (month <= 9) {
			return "0" + month;
		}
		return month + "";
	}

	/**
	 * 获取当月的当天
	 */
	public static String getDayofMonth() {
		Calendar cal = Calendar.getInstance();
		int day = cal.get(Calendar.DAY_OF_MONTH);
		if (day <= 9) {
			return "0" + day;
		}
		return day + "";
	}

	/**
	 * 获取HHmmss格式
	 */
	public static String getHHmmss(Date date) {
		SimpleDateFormat sdfTime = new SimpleDateFormat("HHmmss");
		return sdfTime.format(date);
	}

	/**
	 * 获取HHmmssSSS格式
	 */
	public static String getHHmmssSSS(Date date) {
		SimpleDateFormat sdfTime = new SimpleDateFormat("HHmmssSSS");
		return sdfTime.format(date);
	}

	/**
	 * 获取yyyy-MM-dd格式
	 */
	public static String getYYYY_MM(Date date) {
		if (date == null) {
			return null;
		}
		
		return sdfYYYY_MM.format(date);
	}

	/**
	 * 获取yyyy-MM-dd格式
	 */
	public static String getYYYY_MM_DD(Date date) {
		
		return sdfYYYY_MM_DD.format(date);
	}

	/**
	 * 获取yyyy-MM-dd格式
	 */
	public static String getYyyy_MM_dd_HH_mm_ss(Date date) {
		return sdfYYYY_MM_DD_HH_mm_ss.format(date);
	}

	/**
	 * 计算两个日期之间相差的天数
	 */
	public static int getDaysBetween(Date beginDate, Date endDate) {
		
		beginDate = DateUtil.parseYYYY_MM_dd(DateUtil.getYYYY_MM_DD(beginDate));
		endDate = DateUtil.parseYYYY_MM_dd(DateUtil.getYYYY_MM_DD(endDate));
		
		return (int) ((endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000));
	}

	/**
	 * 计算两个日期之间相差的天数
	 */
	public static int getDaysBetween(String beginYYYYMMdd, String endYYYYMMdd) {
		Date beginDate = DateUtil.parseYYYY_MM_dd(beginYYYYMMdd);
		Date endDate = DateUtil.parseYYYY_MM_dd(endYYYYMMdd);
		endDate = DateUtil.parseYYYY_MM_dd(DateUtil.getYYYY_MM_DD(endDate));
		
		return (int) ((endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000));
	}

	/**
	 * 获取当月第一天
	 */
	public static String getFirstDayByMonth() {
		String firstday = "";
		Calendar cale = Calendar.getInstance();
		cale = Calendar.getInstance();
		cale.add(Calendar.MONTH, 0);
		cale.set(Calendar.DAY_OF_MONTH, 1);
		firstday = sdfYYYY_MM_DD.format(cale.getTime());
		return firstday + " 00:00:00";
	}
	
	/**
	 * 获取今年某月的第一天
	 */
	public static String getFirstDayByMonth(int month) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy");
		String year = format.format(new Date());
		Calendar cal = Calendar.getInstance();  
        //设置年份  
        cal.set(Calendar.YEAR, Integer.valueOf(year));  
        //设置月份  
        cal.set(Calendar.MONTH, month-1);  
        //获取某月最小天数  
        int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);  
        //设置日历中月份的最小天数  
        cal.set(Calendar.DAY_OF_MONTH, firstDay);  
        //格式化日期  
        String firstDayOfMonth = sdfYYYY_MM_DD.format(cal.getTime());  
        return firstDayOfMonth + " 00:00:00";
	}
	
	/**
	 * 获取某年某月的第一天
	 */
	public static String getFirstDayByMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();  
        //设置年份  
        cal.set(Calendar.YEAR, year);  
        //设置月份  
        cal.set(Calendar.MONTH, month-1);  
        //获取某月最小天数  
        int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);  
        //设置日历中月份的最小天数  
        cal.set(Calendar.DAY_OF_MONTH, firstDay);  
        //格式化日期  
        String firstDayOfMonth = sdfYYYY_MM_DD.format(cal.getTime());  
        return firstDayOfMonth + " 00:00:00";
	}
	
	/**
	 * 获取今年某月最后一天
	 */
	public static String getLastDayByMonth(int month) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy");
		String year = format.format(new Date());
		Calendar cal = Calendar.getInstance();  
        //设置年份  
        cal.set(Calendar.YEAR, Integer.valueOf(year));  
        //设置月份  
        cal.set(Calendar.MONTH, month-1);  
        //获取某月最大天数  
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);  
        //设置日历中月份的最大天数  
        cal.set(Calendar.DAY_OF_MONTH, lastDay);  
        //格式化日期  
        String lastDayOfMonth = sdfYYYY_MM_DD.format(cal.getTime());  
        return lastDayOfMonth + " 23:59:59";
	}
	
	/**
	 * 获取某年某月最后一天
	 */
	public static String getLastDayByMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();  
        //设置年份  
        cal.set(Calendar.YEAR, year);  
        //设置月份  
        cal.set(Calendar.MONTH, month-1);  
        //获取某月最大天数  
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);  
        //设置日历中月份的最大天数  
        cal.set(Calendar.DAY_OF_MONTH, lastDay);  
        //格式化日期  
        String lastDayOfMonth = sdfYYYY_MM_DD.format(cal.getTime());  
        return lastDayOfMonth + " 23:59:59";
	}

	/**
	 * 获取当月最后一天
	 */
	public static String getLastDayByMonth() {
		Calendar cale = Calendar.getInstance();
		String lastday = "";
		cale = Calendar.getInstance();
		cale.add(Calendar.MONTH, 1);
		cale.set(Calendar.DAY_OF_MONTH, 0);
		lastday = sdfYYYY_MM_DD.format(cale.getTime());
		return lastday + " 23:59:59";
	}

	/**
	 * 获取日期当天的开始时间
	 */
	public static Date dateOfBegin(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);

		return c.getTime();
	}

	/**
	 * 获取日期当天的结束时间
	 */
	public static Date dateOfEnd(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);

		return c.getTime();
	}

	/**
	 * 获取日期当天的开始时间
	 */
	public static Date tomorrowOfBegin(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DATE, 1);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);

		return c.getTime();
	}
	
	public static Date substract(Date date, Integer num) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DATE, num * -1);
		
		return c.getTime();
	}

	/**
	 * 获取日期当月的开始时间
	 */
	public static Date monthOfBegin(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, 1);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);

		return c.getTime();
	}

	/**
	 * 获取日期上月的开始时间
	 */
	public static Date lastMonthOfBegin(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, -1);
		c.set(Calendar.DAY_OF_MONTH, 1);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);

		return c.getTime();
	}

	/**
	 * 获取日期下月的开始时间
	 */
	public static Date nextMonthOfBegin(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, 1);
		c.set(Calendar.DAY_OF_MONTH, 1);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);

		return c.getTime();
	}
	
	/**
	 * 获取两个时间点之间的随机时间
	 * @param startTime 开始的时间
	 * @param endTime 结束的时间
	 * @return
	 */
	public static Date randomTime(Date startTime, Date endTime) {
		long startLong = startTime.getTime();
		long endLong = endTime.getTime();
		long rtn = startLong + (long)(Math.random() * (endLong - startLong));
		
		//如果返回的是开始时间和结束时间，通过递归调用本函数查找随机值
	    if(rtn == startLong || rtn == endLong){
	        return randomTime(startTime, endTime);
	    }
		return new Date(rtn);
	}

	public static void main(String[] args) throws ParseException {
		
//		Date dateNow = new Date();

		System.out.println(DateUtil.parseYMdHms("2020-05-12 09:00:00"));
		
	}
}
